/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BL;
import BE.BEGrafoAlmacen;
import BE.BENodo;
import java.util.ArrayList;
import java.util.List;
import BL.BLRack;
import BE.BEPosicion;
import BE.BEPallet;
import BE.BEPosicionxRack;
import BE.BENodoDespacho;
import BE.BERackxNodo;
import BE.BERack;
/**
 *
 * @author Elessar
 */
public class BLGrafoAlmacen {
    BEGrafoAlmacen beGrafoAlmacen;
    ArrayList<ArrayList<BENodo>> lstResultados;
    ArrayList<BEPosicionxRack> lstPosicionxRack = new ArrayList<BEPosicionxRack>();
    List<BENodo> nodosObligatorios = new ArrayList<BENodo>();
    List<BERackxNodo> lstRackxNodo;
    List<BERack> lstRacks;

    public List<BERackxNodo> getLstRackxNodo() {
        return lstRackxNodo;
    }

    public void setLstRackxNodo(List<BERackxNodo> lstRackxNodo) {
        this.lstRackxNodo = lstRackxNodo;
    }

    public BEGrafoAlmacen getBeGrafoAlmacen() {
        return beGrafoAlmacen;
    }

    public void setBeGrafoAlmacen(BEGrafoAlmacen beGrafoAlmacen) {
        this.beGrafoAlmacen = beGrafoAlmacen;
    }

    public ArrayList<ArrayList<BENodo>> getLstResultados() {
        return lstResultados;
    }

    public void setLstResultados(ArrayList<ArrayList<BENodo>> lstResultados) {
        this.lstResultados = lstResultados;
    }
    
    public BLGrafoAlmacen(int n, int m){
        beGrafoAlmacen = new BEGrafoAlmacen(n,m);
        lstResultados = new ArrayList<ArrayList<BENodo>>();
        lstRackxNodo = new ArrayList<BERackxNodo>();
    }
    
    public void agregarRack (int xRack, int yRack, int longitud, BERack rack){
        //comprobar si puede agregarse el rack
        int idnodo=(yRack-1)*beGrafoAlmacen.getN()+xRack;
        for (int i=0; i<longitud; i++){
            if (verificarNodoOcupado(idnodo+beGrafoAlmacen.getN()*i)){
                System.out.println("El Rack no puede agregarse en la posición (x,y): ("+xRack+","+yRack+")");
                return;}
        }
        BERackxNodo aux = new BERackxNodo();
        aux.setBeRack(rack);
        for (int i=0; i<longitud; i++){
            anularNodo(idnodo+beGrafoAlmacen.getN()*i);
            beGrafoAlmacen.getGrafo().get(idnodo+beGrafoAlmacen.getN()*i-1).setIdrack(rack.getIdRack());
            aux.getLstNodo().add(beGrafoAlmacen.getGrafo().get(idnodo+beGrafoAlmacen.getN()*i-1));
        }
        beGrafoAlmacen.setCantRacks(beGrafoAlmacen.getCantRacks()+1);
        lstRackxNodo.add(aux);
    }
    
    public boolean verificarNodoOcupado(int idnodo){
        if (beGrafoAlmacen.getAnulados().contains(idnodo))
            return true;
        return false;
    }
    
    public void anularNodo (int idnodo){
        BENodo nodoActual = beGrafoAlmacen.getGrafo().get(idnodo-1);
        int idnodoAux;
        for (int i=0; i<nodoActual.getVecinos().size(); i++){
            idnodoAux = nodoActual.getVecinos().get(i).getIdNodo();
            for (int j=0; j<beGrafoAlmacen.getGrafo().get(idnodoAux-1).getVecinos().size(); j++)
                if (beGrafoAlmacen.getGrafo().get(idnodoAux-1).getVecinos().get(j).getIdNodo()==idnodo){
                    beGrafoAlmacen.getGrafo().get(idnodoAux-1).getVecinos().remove(j);
                    break;
                }
        }
        beGrafoAlmacen.getGrafo().get(idnodo-1).getVecinos().clear();
        beGrafoAlmacen.getAnulados().add(idnodo);
    }
    
    public String imprimeRuta (List<BENodo> ruta, ArrayList<Integer> obligatorios, String accion){
        if (ruta.get(0).getIdNodo()==1){
            ruta.get(0).setX(1);
            ruta.get(0).setY(1);
        }
        int cont=1;
        int contAbajo=0, contArriba=0, contIzquierda=0, contDerecha=0;
        String linea="";
        int direccion=0;
        //0: hacia arriba (inicial) (y creciendo)
        //1: hacia la derecha (x creciendo)
        //2: hacia la izquierda (x disminuyendo)
        //3: hacia abajo (y disminuyendo)
        
        for (int i=0; i<ruta.size()-1; i++){
            //linea+=cont+") ";
            String auxPos = "(C"+ruta.get(i).getX()+",F"+ruta.get(i).getY()+")";
            if (ruta.get(i).getX()<ruta.get(i+1).getX() && ruta.get(i).getY()==ruta.get(i+1).getY()){
                //hacia la derecha, x creciendo
                
                if (contIzquierda>0 || contArriba>0 || contAbajo>0){
                    //linea+=cont+") Avanzar "+(contIzquierda+contArriba+contAbajo)+" espacios por la fila "+ruta.get(i).getX()+" hasta la columna "+ruta.get(i).getY()+" en el mapa.\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i).getY()+" hasta la columna "+ruta.get(i).getX()+" en el mapa.\n";
                    cont++;
                }
                else if (obligatorios.contains(ruta.get(i).getIdNodo())){
                    //linea+=cont+") Avanzar "+(contDerecha)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i).getY()+" hasta la columna "+ruta.get(i).getX()+" en el mapa.\n";
                    contDerecha=0;
                    cont++;
                }
                contDerecha++;
                contIzquierda=0;
                contArriba=0;
                contAbajo=0;
                
                while (obligatorios.contains(ruta.get(i).getIdNodo())){
                //linea+=" \n";
                int index = obligatorios.indexOf(ruta.get(i).getIdNodo());
                int fila=0, columna=0,rack;
                fila = lstPosicionxRack.get(index).getFila();
                //fila=ruta.get(i).getX();
                columna = lstPosicionxRack.get(index).getColumna();
                //columna=ruta.get(i).getY();
                rack=lstPosicionxRack.get(index).getIdrack();
                //linea+=cont+") (DES)CARGAR PALLET | Pos:"+auxPos+" (Rack:"+rack+ "| Fil:"+fila+"| Col:"+columna+")\n";
                linea+=cont+") "+accion+" Pallet (Rack:"+rack+ "| Nivel:"+fila+"| Columna:"+columna+") [Posicion Mapa: "+auxPos+"]\n";
                cont++;
                //int index2 = obligatorios.indexOf(ruta.get(i).getIdNodo());
                obligatorios.remove(index);
                lstPosicionxRack.remove(index);
                
                }
                
                if (i==(ruta.size()-1-1) && (contDerecha+contIzquierda+contArriba+contAbajo)>0){
                //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contArriba+contAbajo)+" espacios "+auxPos+". FIN\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i+1).getY()+" hasta la columna "+ruta.get(i+1).getX()+" en el mapa.\n";
                } 
                
                switch(direccion){
                    case 0: linea+= cont+") Doblar a la izquierda\n";
                        cont++;
                        direccion=1;
                        break;
                    case 1: //linea+= "Avanzar 1 espacio";
                        //direccion=1;
                        break;
                    case 2: linea+= cont+") Dar media vuelta\n";
                        direccion=1;
                        cont++;
                        break;
                    case 3: linea+= cont+") Doblar a la derecha\n";
                        direccion=1;
                        cont++;
                        break;
                }
            }
            if (ruta.get(i).getX()>ruta.get(i+1).getX() && ruta.get(i).getY()==ruta.get(i+1).getY()){
                //hacia la izquierda, x disminuyendo
                
                if (contDerecha>0 || contArriba>0 || contAbajo>0){
                    //linea+=cont+") Avanzar "+(contDerecha+contArriba+contAbajo)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i).getY()+" hasta la columna "+ruta.get(i).getX()+" en el mapa.\n";
                    cont++;
                }
                else if (obligatorios.contains(ruta.get(i).getIdNodo())){
                    //linea+=cont+") Avanzar "+(contIzquierda)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i).getY()+" hasta la columna "+ruta.get(i).getX()+" en el mapa.\n";
                    contIzquierda=0;
                    cont++;
                }
                contDerecha=0;
                contIzquierda++;
                contArriba=0;
                contAbajo=0;
                
                while (obligatorios.contains(ruta.get(i).getIdNodo())){
                //linea+=" \n";
                int index = obligatorios.indexOf(ruta.get(i).getIdNodo());
                int fila=0, columna=0,rack;
                fila = lstPosicionxRack.get(index).getFila();
                //fila=ruta.get(i).getX();
                columna = lstPosicionxRack.get(index).getColumna();
                //columna=ruta.get(i).getY();
                rack=lstPosicionxRack.get(index).getIdrack();
                //linea+=cont+") (DES)CARGAR PALLET | Pos:"+auxPos+" (Rack:"+rack+ "| Fil:"+fila+"| Col:"+columna+")\n";
                linea+=cont+") "+accion+" Pallet (Rack:"+rack+ "| Nivel:"+fila+"| Columna:"+columna+") [Posicion Mapa: "+auxPos+"]\n";
                cont++;
                //int index2 = obligatorios.indexOf(ruta.get(i).getIdNodo());
                obligatorios.remove(index);
                lstPosicionxRack.remove(index);
                
                }
                
                if (i==(ruta.size()-1-1) && (contDerecha+contIzquierda+contArriba+contAbajo)>0){
                //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contArriba+contAbajo)+" espacios "+auxPos+". FIN\n";
                    linea+=cont+") Avanzar por la fila "+ruta.get(i+1).getY()+" hasta la columna "+ruta.get(i+1).getX()+" en el mapa.\n";
                } 
                
                switch(direccion){
                    case 0: linea+= cont+") Doblar a la derecha\n";
                        direccion=2;
                        cont++;
                        break;
                    case 1: linea+= cont+") Dar media vuelta\n";
                        direccion=2;
                        cont++;
                        break;
                    case 2: //linea+= "Avanzar 1 espacio";
                        break;
                    case 3: linea+= cont+") Doblar a la izquierda\n";
                        direccion=2;
                        cont++;
                        break;
                }
            }
            if (ruta.get(i).getX()==ruta.get(i+1).getX() && ruta.get(i).getY()<ruta.get(i+1).getY()){
                //hacia arriba, y creciendo
                
                if (contDerecha>0 || contIzquierda>0 || contAbajo>0){
                    //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contAbajo)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i).getX()+" hasta la fila "+ruta.get(i).getY()+" en el mapa.\n";
                    cont++;
                }
                else if (obligatorios.contains(ruta.get(i).getIdNodo())){
                    //linea+=cont+") Avanzar "+(contArriba)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i).getX()+" hasta la fila "+ruta.get(i).getY()+" en el mapa.\n";
                    contArriba=0;
                    cont++;
                }
                contDerecha=0;
                contIzquierda=0;
                contArriba++;
                contAbajo=0;
                
                while (obligatorios.contains(ruta.get(i).getIdNodo())){
                //linea+=" \n";
                int index = obligatorios.indexOf(ruta.get(i).getIdNodo());
                int fila=0, columna=0,rack;
                fila = lstPosicionxRack.get(index).getFila();
                //fila=ruta.get(i).getX();
                columna = lstPosicionxRack.get(index).getColumna();
                //columna=ruta.get(i).getY();
                rack=lstPosicionxRack.get(index).getIdrack();
                //linea+=cont+") (DES)CARGAR PALLET | Pos:"+auxPos+" (Rack:"+rack+ "| Fil:"+fila+"| Col:"+columna+")\n";
                linea+=cont+") "+accion+" Pallet (Rack:"+rack+ "| Nivel:"+fila+"| Columna:"+columna+") [Posicion Mapa: "+auxPos+"]\n";
                cont++;
                //int index2 = obligatorios.indexOf(ruta.get(i).getIdNodo());
                obligatorios.remove(index);
                lstPosicionxRack.remove(index);
                
                }
                
                if (i==(ruta.size()-1-1) && (contDerecha+contIzquierda+contArriba+contAbajo)>0){
                //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contArriba+contAbajo)+" espacios "+auxPos+". FIN\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i+1).getX()+" hasta la fila "+ruta.get(i+1).getY()+" en el mapa.\n";
                } 
                
                switch(direccion){
                    case 0: //linea+= "Avanzar 1 espacio";
                        break;
                    case 1: linea+= cont+") Doblar a la derecha\n";
                        direccion=0;
                        cont++;
                        break;
                    case 2: linea+= cont+") Doblar a la izquierda\n";
                        direccion=0;
                        cont++;
                        break;
                    case 3: linea+= cont+") Dar media vuelta\n";
                        direccion=0;
                        cont++;
                        break;
                }
            }
            if (ruta.get(i).getX()==ruta.get(i+1).getX() && ruta.get(i).getY()>ruta.get(i+1).getY()){
                //hacia abajo, y disminuyendo
                
                if (contDerecha>0 || contIzquierda>0 || contArriba>0){
                    //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contArriba)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i).getX()+" hasta la fila "+ruta.get(i).getY()+" en el mapa.\n";
                    cont++;
                }
                else if (obligatorios.contains(ruta.get(i).getIdNodo())){
                    //linea+=cont+") Avanzar "+(contAbajo)+" espacios "+auxPos+"\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i).getX()+" hasta la fila "+ruta.get(i).getY()+" en el mapa.\n";
                    contAbajo=0;
                    cont++;
                }
                contDerecha=0;
                contIzquierda=0;
                contArriba=0;
                contAbajo++;
                
                while (obligatorios.contains(ruta.get(i).getIdNodo())){
                //linea+=" \n";
                int index = obligatorios.indexOf(ruta.get(i).getIdNodo());
                int fila=0, columna=0,rack;
                fila = lstPosicionxRack.get(index).getFila();
                //fila=ruta.get(i).getX();
                columna = lstPosicionxRack.get(index).getColumna();
                //columna=ruta.get(i).getY();
                rack=lstPosicionxRack.get(index).getIdrack();
                linea+=cont+") "+accion+" Pallet (Rack:"+rack+ "| Nivel:"+fila+"| Columna:"+columna+") [Posicion Mapa: "+auxPos+"]\n";
                cont++;
                //int index2 = obligatorios.indexOf(ruta.get(i).getIdNodo());
                obligatorios.remove(index);
                lstPosicionxRack.remove(index);
                
                }
                
                if (i==(ruta.size()-1-1) && (contDerecha+contIzquierda+contArriba+contAbajo)>0){
                //linea+=cont+") Avanzar "+(contDerecha+contIzquierda+contArriba+contAbajo)+" espacios "+auxPos+". FIN\n";
                    linea+=cont+") Avanzar por la columna "+ruta.get(i+1).getX()+" hasta la fila "+ruta.get(i+1).getY()+" en el mapa.\n";
                } 
                
                switch(direccion){
                    case 0: linea+= cont+") Dar media vuelta\n";
                        direccion=3;
                        cont++;
                        break;
                    case 1: linea+= cont+") Doblar a la izquierda\n";
                        direccion=3;
                        cont++;
                        break;
                    case 2: linea+= cont+") Doblar a la derecha\n";
                        direccion=3;
                        cont++;
                        break;
                    case 3: //linea+= "Avanzar 1 espacio";
                        break;
                }
            }       
                     
                                  
        }
        return linea;
    }
    
    
    
    public int buscarNodoRutaRack (int x, int y){
        int idnodoRack = (y-1)*beGrafoAlmacen.getN()+x;
        int idnodoIzq = idnodoRack-1;
        int idnodoDer = idnodoRack+1;        
        if (!beGrafoAlmacen.getAnulados().contains(idnodoIzq))
            return idnodoIzq;
        if (!beGrafoAlmacen.getAnulados().contains(idnodoDer))
            return idnodoDer;
        System.out.println("ERROR: Rack mal ubicado");
        return -1;
    }
    
    public void guardarResultado(ArrayList<BENodo> resultado){
        lstResultados.add(resultado);
    }
    
    public void limpiarResultados (){
        lstResultados.clear();
    }
    
    public ArrayList<BENodo> getMejorResultado (){
        int minIndex=-1;
        int minLongitud=-1;
        for (int i=0; i<lstResultados.size(); i++){
            if (i==0) {
                minLongitud=getLongitudRuta(lstResultados.get(i));
                minIndex=i;
            }
            if (minLongitud<getLongitudRuta(lstResultados.get(i))){
                minIndex=i;
                minLongitud=getLongitudRuta(lstResultados.get(i));                
            }
        }
        if (minIndex>-1)
            return lstResultados.get(minIndex);
        else return null;
    }
    
    public int getLongitudRuta (ArrayList<BENodo> ruta){
        return ruta.size()-1;
    }
    
    public void cargarRacks(){
        int longitud;
        BEPosicion posRack;        
        BLRack blRack = new BLRack();
        blRack.cargar();
        for (int i=0; i<blRack.getLstRacks().size(); i++){
            posRack=blRack.getLstRacks().get(i).getPosicion();
            longitud=blRack.getLstRacks().get(i).getNumeroColumnas();
            agregarRack(posRack.getFila(), posRack.getColumna(), longitud, blRack.getLstRacks().get(i));
        }
        this.lstRacks=blRack.getLstRacks();
    }
    
    public ArrayList<Integer> calcularObligatorios (List<BEPallet> lstPallets){
        int x,y,idrack,idnodo;
        BLRack blRack = new BLRack();
        ArrayList<Integer> obligatorios = new ArrayList<Integer>();
        for (int i=0; i<lstPallets.size(); i++){
//            if (lstPallets.get(i).getPosicionxrack()!=null)
//                idrack=lstPallets.get(i).getPosicionxrack().getIdrack();
//            else 
//            if (lstPallets.get(i).getIdPallet()==13) idrack=77;
//            else 
            idrack=lstPallets.get(i).getPosicionxrack().getIdrack();
            x=blRack.getRackbyId(idrack).getPosicion().getFila();
            y=blRack.getRackbyId(idrack).getPosicion().getColumna()+lstPallets.get(i).getPosicionxrack().getColumna()-1;
            //idnodo=(y-1)*beGrafoAlmacen.getN()+x;
            obligatorios.add(buscarNodoRutaRack(x, y));
            //nodosObligatorios.add(new BENodo(getIdNodoXY(x, y),x,y));
            nodosObligatorios.add(beGrafoAlmacen.getGrafo().get(buscarNodoRutaRack(x,y)-1));
            lstPosicionxRack.add(lstPallets.get(i).getPosicionxrack());
        }
        return obligatorios;
    }
    
//    public List<BENodo> getNodosObligatorios (){
//        for (int)
//    }
    
    public int getIdNodoXY (int x, int y){
        return (y-1)*beGrafoAlmacen.getN()+x;
    }
    
    public boolean verificarXYocupado(int x, int y){
        if (beGrafoAlmacen.getAnulados().contains(getIdNodoXY(x,y)))
            return true;
        return false;
    }
    
    
    public List<BENodo> generarRutaAlmacen(List<BENodo> ruta){
        ruta.add(0, beGrafoAlmacen.getGrafo().get(0));
        ruta.add(beGrafoAlmacen.getGrafo().get(0));
        List<BENodo> auxRuta = new ArrayList<BENodo>();
        auxRuta.add(beGrafoAlmacen.getGrafo().get(0));
        //la ruta tiene el origen (1,1) al inicio y al final
        for (int i=0; i<ruta.size()-1;i++){
            List<BENodo> rutaParcial = generarRutaParcial(ruta.get(i),ruta.get(i+1));
            auxRuta.addAll(rutaParcial);
            //auxRuta.add(beGrafoAlmacen.getGrafo().get(getIdNodoXY(ruta.get(i+1).getX(), ruta.get(i+1).getY())-1));
        }     
        return auxRuta;
    }
        
    public List<BENodo> generarRutaParcial(BENodo nodo1, BENodo nodo2){
        List<BENodo> auxRuta = new ArrayList<BENodo>();
        BENodo nodoActual = nodo1;
        BENodo nodoAnt;
        
        //ubicarme en la misma columna (x) que el punto destino
        if (nodo1.getX()<nodo2.getX()){
            while (nodoActual.getX()<nodo2.getX()){
                nodoAnt = nodoActual;
                nodoActual = derecha(nodoActual);
                
                if (nodoActual==null){
                    int yArriba = getYDerArriba(nodoAnt);
                    int yAbajo = getYDerAbajo(nodoAnt);
                    int dA = Math.abs(yArriba-nodoAnt.getY());
                    int eA = Math.abs(yArriba-nodo2.getY());
                    int dB = Math.abs(yAbajo-nodoAnt.getY());
                    int eB = Math.abs(yAbajo-nodo2.getY());
                    
                    nodoActual = nodoAnt;
                    if (dA+eA<dB+eB){
                        while(nodoActual.getY()>yArriba){
                            nodoActual=subir(nodoActual);
                            auxRuta.add(nodoActual);
                        }
                    }
                    if (dA+eA>=dB+eB){
                        while(nodoActual.getY()<yAbajo){
                            nodoActual=bajar(nodoActual);
                            auxRuta.add(nodoActual);
                        }
                    }
                }
                else {
                    auxRuta.add(nodoActual);
                }
            }
        }
        else if (nodo1.getX()>nodo2.getX()){
            while (nodoActual.getX()>nodo2.getX()){
                nodoAnt = nodoActual;
                nodoActual = izquierda(nodoActual);
                
                if (nodoActual==null){
                    int yArriba = getYIzqArriba(nodoAnt);
                    int yAbajo = getYIzqAbajo(nodoAnt);
                    int dA = Math.abs(yArriba-nodoAnt.getY());
                    int eA = Math.abs(yArriba-nodo2.getY());
                    int dB = Math.abs(yAbajo-nodoAnt.getY());
                    int eB = Math.abs(yAbajo-nodo2.getY());
                    
                    nodoActual = nodoAnt;
                    if (dA+eA<dB+eB){
                        while(nodoActual.getY()>yArriba){
                            nodoActual=subir(nodoActual);
                            auxRuta.add(nodoActual);
                        }
                    }
                    if (dA+eA>=dB+eB){
                        while(nodoActual.getY()<yAbajo){
                            nodoActual=bajar(nodoActual);
                            auxRuta.add(nodoActual);
                        }
                    }
                }
                else {
                    auxRuta.add(nodoActual);
                }
            }
        }
        
        //subir o bajar...
        if (nodoActual.getY()<nodo2.getY()){
            while (nodoActual.getY()<nodo2.getY()){
                nodoActual=bajar(nodoActual);
                auxRuta.add(nodoActual);
            }
        }
        else if (nodoActual.getY()>nodo2.getY()){
            while (nodoActual.getY()>nodo2.getY()){
                nodoActual=subir(nodoActual);
                auxRuta.add(nodoActual);
            }
        }
                
        return auxRuta;
    }
    
    public BENodo subir (BENodo nodo){
        return beGrafoAlmacen.getGrafo().get(getIdNodoXY(nodo.getX(), nodo.getY()-1)-1);
    }
    
    public BENodo bajar (BENodo nodo){
        return beGrafoAlmacen.getGrafo().get(getIdNodoXY(nodo.getX(), nodo.getY()+1)-1);
    }
    
    public BENodo izquierda (BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()-1, nodo.getY());
        if (verificarNodoOcupado(idnodo)) return null;
        else return beGrafoAlmacen.getGrafo().get(idnodo-1);
    }
    
    public BENodo derecha (BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()+1, nodo.getY());
        if (verificarNodoOcupado(idnodo)) return null;
        else return beGrafoAlmacen.getGrafo().get(idnodo-1);
    }
    
    public int getYDerArriba(BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()+1, nodo.getY());
        BENodo nodoAux = beGrafoAlmacen.getGrafo().get(idnodo-1);
        while (verificarNodoOcupado(idnodo)){
            nodoAux = subir(nodoAux);
            idnodo = nodoAux.getIdNodo();
        }
        return nodoAux.getY();
    }
    
    public int getYDerAbajo(BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()+1, nodo.getY());
        BENodo nodoAux = beGrafoAlmacen.getGrafo().get(idnodo-1);
        while (verificarNodoOcupado(idnodo)){
            nodoAux = bajar(nodoAux);
            idnodo = nodoAux.getIdNodo();
        }
        return nodoAux.getY();
    }
    
    public int getYIzqArriba(BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()-1, nodo.getY());
        BENodo nodoAux = beGrafoAlmacen.getGrafo().get(idnodo-1);
        while (verificarNodoOcupado(idnodo)){
            nodoAux = subir(nodoAux);
            idnodo = nodoAux.getIdNodo();
        }
        return nodoAux.getY();
    }
    
    public int getYIzqAbajo(BENodo nodo){
        int idnodo = getIdNodoXY(nodo.getX()-1, nodo.getY());
        BENodo nodoAux = beGrafoAlmacen.getGrafo().get(idnodo-1);
        while (verificarNodoOcupado(idnodo)){
            nodoAux = bajar(nodoAux);
            idnodo = nodoAux.getIdNodo();
        }
        return nodoAux.getY();
    }
    
    public List<BENodo> getNodosDespachoImpresion (ArrayList<BENodoDespacho> nodosDespacho){
        List<BENodo> lstNodos = new ArrayList<BENodo>();
        for (int i=0; i<nodosDespacho.size(); i++){
            int idnodo = getIdNodoXY(nodosDespacho.get(i).getX(), nodosDespacho.get(i).getY());
            lstNodos.add(beGrafoAlmacen.getGrafo().get(idnodo-1));
        }
        return lstNodos;
    }
    
    public List<BENodo> getNodosDespachoImpresionDePallet (List<BEPallet> lstPallets){
        List<BENodo> lstNodos = new ArrayList<BENodo>();
        int x,y,idrack,idnodo;
        BLRack blRack = new BLRack();  
        blRack.cargar();
        for (int i=0; i<lstPallets.size(); i++){
//            if (lstPallets.get(i).getPosicionxrack()!=null)
//                idrack=lstPallets.get(i).getPosicionxrack().getIdrack();
//            else 
//            if (lstPallets.get(i).getIdPallet()==13) idrack=77;
//            else 
            idrack=lstPallets.get(i).getPosicionxrack().getIdrack();
            x=blRack.getRackfromLst(idrack).getPosicion().getFila();
            y=blRack.getRackfromLst(idrack).getPosicion().getColumna()+lstPallets.get(i).getPosicionxrack().getColumna()-1;            
            lstNodos.add(beGrafoAlmacen.getGrafo().get(getIdNodoXY(x, y)-1));
        }
        return lstNodos;
    }
    
    public List<BENodo> getNodoInternamiento (List<BEPallet> lstPallets){
        List<BENodo> lstNodos = new ArrayList<BENodo>();
        int x,y,idrack,idnodo;
        BLRack blRack = new BLRack();  
        blRack.cargar();
        for (int i=0; i<lstPallets.size(); i++){
            idrack=lstPallets.get(i).getPosicionxrack().getIdrack();
            x=blRack.getRackfromLst(idrack).getPosicion().getFila();
            y=blRack.getRackfromLst(idrack).getPosicion().getColumna()+lstPallets.get(i).getPosicionxrack().getColumna()-1;
            idnodo = buscarNodoRutaRack(x,y);
            lstNodos.add(beGrafoAlmacen.getGrafo().get(idnodo-1));
        }
        return lstNodos;
    }

    public List<BENodo> getNodosObligatorios() {
        return nodosObligatorios;
    }
    
    public String imprimirPallets(List<BEPallet> lstPallets){
        String aux="\n";
        for (int i=0; i<lstPallets.size(); i++){
            aux+=(i+1)+") Pallet:"+lstPallets.get(i).getIdPallet()
                    +" \n   Producto:"+lstPallets.get(i).getProducto().getIdProducto()+"-"+lstPallets.get(i).getProducto().getNombre()
                    +"\n   Rack:"+lstPallets.get(i).getPosicionxrack().getIdrack()
                     +" Columna:"+lstPallets.get(i).getPosicionxrack().getColumna()+" Nivel:"+lstPallets.get(i).getPosicionxrack().getFila()
                    +"\n   Cantidad:"+lstPallets.get(i).getCantidad() +" | Fecha Vencimiento:"+lstPallets.get(i).getFechaVencimiento()+"\n";
        }
        return aux;
    }
    
}